home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’89 / gadlife / source (ugly) / dialogs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-08  |  9.9 KB  |  337 lines  |  [TEXT/KAHL]

  1. #include "main.h"
  2. #include "dialogs.h"
  3.  
  4. static int        myVol;
  5.  
  6. /*******************************************************
  7. *                                                                *
  8. *    Gets info needed for later, when we may be dumping source code, and we need    *
  9. *    to open our own data fork to get the file from.  There does not seem to be any    *
  10. *    good way of finding out the volume the file is in at any time but startup.        *
  11. *                                                                *
  12. *******************************************************/
  13.  
  14. initDialogs() {
  15.     int        errno;
  16.     char        tempStr[ pasStrLen ];
  17.  
  18.     if( errno = GetVol( tempStr, &myVol )) hardPanic( errno, diskPanic );
  19. }
  20.  
  21. /*******************************************************
  22. *                                                                *
  23. *    Filter handles most normal filtering actions required for a dialog.  It assumes    *
  24. *    that the refCon of the dialog contains a refConHandle, and calls the filterProc    *
  25. *    which this identifies to take care of any extra filtering specific to the dialog.    *
  26. *                                                                *
  27. *******************************************************/
  28.  
  29. pascal int filter( theDialog, theEvent, itemHit )
  30.     DialogPtr        theDialog;
  31.     EventRecord    *theEvent;
  32.     int            *itemHit;
  33.     {
  34.     refConHandle    theRefConHand;
  35.     refConPtr        theRefCon;
  36.     int            result = 0;
  37.     char            theChar;
  38.  
  39.     doBackground( nothingElseToDo, noGray, NULL );
  40.     if( theRefConHand = ( refConHandle )GetWRefCon( theDialog )) {
  41.         HLock( theRefConHand );
  42.         theRefCon = *theRefConHand;
  43.         if( theRefCon->filter )
  44.             ( *( theRefCon->filter ))( theDialog, theEvent, itemHit, &( theRefCon->refCon ));
  45.         HUnlock( theRefConHand );
  46.     }
  47.     switch( theEvent->what )
  48.         {
  49.         case updateEvt:
  50.             if( ( DialogPtr )( theEvent->message ) == theDialog )
  51.                 {
  52.                 BeginUpdate( theDialog );
  53.                 drawDefault( theDialog );
  54.                 DrawDialog( theDialog );
  55.                 EndUpdate( theDialog );
  56.                 }
  57.             else    doUpdate( theEvent->message );
  58.             theEvent->what = nullEvent;
  59.             break;
  60.         case keyDown:
  61.             theChar = theEvent->message & charCodeMask;
  62.             if( *itemHit = findButton( theDialog, theChar, theEvent->modifiers ))
  63.                 result = -1;
  64.             break;
  65.         default: ;
  66.         }
  67.     return( result );
  68.     }
  69.  
  70. /*******************************************************
  71. *                                                                *
  72. *    FixButtons updates all of the controls of a dialog so that they have a trivial    *
  73. *    tracking routine.  Obviously this needs to be fixed if I ever need to do any        *
  74. *    special tracking in a dialog.                                        *
  75. *                                                                *
  76. *******************************************************/
  77.  
  78. pascal doNothingAction( theControl, partCode )
  79.     ControlHandle    theControl;
  80.     int            partCode;
  81.     {
  82.     doBackground( someElseToDo, noGray, NULL );
  83.     }
  84.  
  85. fixButtons( theDialog )
  86.     WindowPeek    theDialog;
  87.     {
  88.     ControlHandle    theItem;
  89.     
  90.     theItem = theDialog->controlList;
  91.     while( theItem && *theItem )
  92.         {
  93.         SetCtlAction( theItem, doNothingAction );
  94.         theItem = (**theItem).nextControl;
  95.         }
  96.     }
  97.  
  98. /*******************************************************
  99. *                                                                *
  100. *    This draws an outline around the default button of the given dialog.  It is used    *
  101. *    in response to update events coming through the filterProc.                *
  102. *                                                                *
  103. *******************************************************/
  104.  
  105. drawDefault( theDialog )
  106.     DialogPtr        theDialog;
  107.     {
  108.     ControlHandle    theItem;
  109.     GrafPtr        savePort;
  110.     Rect            theRect;
  111.     PenState        savePen;
  112.     int            type;
  113.     
  114.     GetPort( &savePort );
  115.     SetPort( theDialog );
  116.     GetPenState( &savePen );
  117.     GetDItem( theDialog, (( DialogPeek )theDialog )->aDefItem, &type, &theItem, &theRect );
  118.     PenMode( patOr );
  119.     PenPat( black );
  120.     PenSize( 3, 3 );
  121.     InsetRect( &theRect, -4, -4 );
  122.     FrameRoundRect( &theRect, 16, 16 );
  123.     SetPenState( &savePen );
  124.     SetPort( savePort );
  125.     }
  126.  
  127. /*******************************************************
  128. *                                                                *
  129. *    CenterWindow is simple - it centers the given window horizontally on the main    *
  130. *    screen.  It isn't at all smart about multi-gdevice systems.                    *
  131. *                                                                *
  132. *******************************************************/
  133.  
  134. centerWindow( theWindow )
  135.     WindowPtr    theWindow;
  136.     {
  137.     int            newleft;
  138.     
  139.     newleft = ( screenBits.bounds.right + screenBits.bounds.left
  140.             - theWindow->portRect.right - theWindow->portRect.left ) / 2;
  141.     MoveWindow( theWindow, newleft, theWindow->portRect.top - theWindow->portBits.bounds.top, 0 );
  142.     }
  143.  
  144. /*******************************************************
  145. *                                                                *
  146. *    doDialog handles all of the housekeeping for bringing up a dialog box.  It loads    *
  147. *    the dialog with the given ID, initializes fields appropriately, and runs the        *
  148. *    dialog until it exits.  Its filterProc calls the one given on every event, with the    *
  149. *    address of the stored refCon field, as well as the usual parameters.            *
  150. *                                                                *
  151. *******************************************************/
  152.  
  153. doDialog( id, hitProc, filterProc, refCon )
  154.     int            id;
  155.     int            (*hitProc)(), (*filterProc)();
  156.     long            refCon;
  157. {
  158.     refConHandle    theRefCon;
  159.     WindowPeek    theWindow;
  160.     DialogPtr        theDialog;
  161.     DialogTemplate    **tempHand, *theTemp;
  162.     Handle        items;
  163.     int            itemHit, isDA;
  164.     
  165.     theWindow = ( WindowPeek )FrontWindow();
  166.     isDA = theWindow && theWindow->windowKind < 0;
  167.     if( isDA ) setBadScrap();
  168.     
  169.     tempHand = ( DialogTemplate** )GetResource( 'DLOG', id );
  170.     HLock( tempHand );
  171.     theTemp = *tempHand;
  172.     items = GetResource( 'DITL', theTemp->itemsID );
  173.     HandToHand( &items );
  174.     theDialog = NewDialog(    NULL, &( theTemp->boundsRect ), &( theTemp->title ), 0, theTemp->procID,
  175.                         -1L, theTemp->goAwayFlag, theTemp->refCon, items );
  176.     HUnlock( tempHand );
  177.     theRefCon = ( refConHandle )NewHandle(( long )sizeof( refConData ));
  178.     ( **theRefCon ).filter = filterProc;
  179.     ( **theRefCon ).refCon = refCon;
  180.     SetWRefCon( theDialog, theRefCon );
  181.     fixButtons( theDialog );
  182.     centerWindow( theDialog );
  183.     ShowWindow( theDialog );
  184.     ModalDialog( filter, &itemHit );
  185.     while( itemHit != 1 ) {
  186.         if( hitProc ) ( *hitProc )( theDialog, itemHit );
  187.         ModalDialog( filter, &itemHit );
  188.     }
  189.     DisposHandle( theRefCon );
  190.     DisposDialog( theDialog );
  191.     if( isDA ) exportScrap();
  192. }
  193.  
  194. /*******************************************************
  195. *                                                                *
  196. *    The following routines handle the about box.                            *
  197. *                                                                *
  198. *    AboutFilter makes sure that the free memory count shown in the about box    *
  199. *    is up to date.                                                    *
  200. *                                                                *
  201. *******************************************************/
  202.  
  203. aboutFilter( theDialog, theEvent, itemHit, theRefCon )
  204.     DialogPtr        theDialog;
  205.     EventRecord    *theEvent;
  206.     int            *itemHit;
  207.     long            *theRefCon;
  208.     {
  209.     ControlHandle    item;
  210.     Rect            box;
  211.     long            newFree;
  212.     int            type;
  213.     char            *num, memFree[ numStrLen ];
  214.     
  215.     newFree = FreeMem();
  216.     if( newFree != *theRefCon )
  217.         {
  218.         *theRefCon = newFree;
  219.         displayNumPas( newFree, memFree + numStrLen - 1, &num );
  220.         GetDItem( theDialog, 4, &type, &item, &box );
  221.         SetIText( item, num );
  222.         }
  223.     }
  224.  
  225. /*******************************************************
  226. *                                                                *
  227. *    AboutHit will only be called when the source button is pressed, so it need not    *
  228. *    pay attention to its parameters.                                     *
  229. *                                                                *
  230. *    DumpSource requests a filename to deposit the source code into, and if one is    *
  231. *    given it calls copyFromDataFork to copy the source code (compressed) out     of    *
  232. *    the data fork of the application into the named file.  The default and prompt    *
  233. *    strings should be stored as resources.                                *
  234. *                                                                *
  235. *******************************************************/
  236.  
  237. aboutHit( theDialog, itemHit )
  238.     DialogPtr        theDialog;
  239.     int            itemHit;
  240.     {
  241.     dumpSource();
  242.     }
  243.  
  244. dumpSource()
  245.     {
  246.     static Point    where = { 70, 100 };
  247.     static char    prompt[25] = "\pDestination Filename:",
  248.                 destName[25] = "\pLife Source.sit";
  249.     SFReply        reply;
  250.     
  251.     installModalTrap();
  252.     SFPutFile( where, prompt, destName, NULL, &reply );
  253.     removeModalTrap();
  254.     if( reply.good ) copyFromDataFork( reply.fName, reply.vRefNum );
  255.     }
  256.     
  257. /*******************************************************
  258. *                                                                *
  259. *    CopyFromDataFork does just that - given a filename and volume number it        *
  260. *    copies the content of the application's data fork into the named file.  It deletes    *
  261. *    the file if it is there already, and tries to create it if it is not.                *
  262. *                                                                *
  263. *******************************************************/
  264.  
  265. copyFromDataFork( name, dest )
  266.     char    *name;
  267.     int        dest;
  268.     {
  269.     Handle    apParam;
  270.     long        count = buf_len;
  271.     int        dref, sref, bad = -1, myResFile;
  272.     char        myName[ pasStrLen ], buffer[ buf_len ];
  273.     
  274.     FSDelete( name, dest );
  275.     if( Create( name, dest, 'SIT!', 'SIT!' )) return( -1 );
  276.     if( !FSOpen( name, dest, &dref ))
  277.         {
  278.         GetAppParms( myName, &myResFile, &apParam );
  279.         if( !FSOpen( myName, myVol, &sref ))
  280.             {
  281.             while( !FSRead( sref, &count, buffer ))
  282.                 FSWrite( dref, &count, buffer );
  283.             FSWrite( dref, &count, buffer );
  284.             FSClose( sref );
  285.             bad = 0;
  286.             }
  287.         FSClose( dref );
  288.         }
  289.     if( bad ) FSDelete( name, dest );
  290.     FlushVol( NULL, dest );
  291.     }
  292.     
  293. /*******************************************************
  294. *                                                                *
  295. *    DoAbout is deceptively simple - it simply calls up the about box, with the        *
  296. *    above routines as the hit and filter routines.  Note that the above filter is        *
  297. *    called by the actual dialog filter routine, which takes care of such things as    *
  298. *    mapping keys to buttons, handling updates, and calling doBackground.            *
  299. *                                                                *
  300. *******************************************************/
  301.  
  302. doAbout()
  303.     {
  304.     long            free;
  305.     char            memFree[13], *num;
  306.  
  307.     free = FreeMem();
  308.     displayNumPas( free, memFree + 12, &num );
  309.     ParamText( num, NULL, NULL, NULL );    
  310.  
  311.     doDialog( aboutDlg, aboutHit, aboutFilter, free );
  312.     }
  313.     
  314. /*******************************************************
  315. *                                                                *
  316. *    What to do when we run into trouble.  Routines here for 'panic' cases, when we    *
  317. *    can't do something that we have committed to doing already.                *
  318. *                                                                *
  319. *******************************************************/
  320.  
  321. hardPanic( errno, which )
  322.     int    errno, which;
  323. {
  324.     softPanic( errno, which );
  325.     ExitToShell();
  326. }
  327.  
  328. softPanic( errno, which )
  329.     int    errno, which;
  330. {
  331.     char            theString[ pasStrLen ], errNoStr[ numStrLen ], *num;
  332.  
  333.     GetIndString( theString, panicStrs, which );
  334.     displayNumPas(( long )which, errNoStr + numStrLen - 1, &num );
  335.     ParamText( theString, num, NULL, NULL );
  336.     doDialog( panicDlg, NULL, NULL, NULL );
  337. }